package com.dy.yunying.biz.service.znfx.impl;

import com.alibaba.fastjson.JSON;
import com.dy.yunying.api.datacenter.vo.AdDataAnalysisVO;
import com.dy.yunying.api.entity.znfx.ChartData;
import com.dy.yunying.api.entity.znfx.ChartDataDetail;
import com.dy.yunying.api.entity.znfx.ChartVO;
import com.dy.yunying.api.enums.ChartTypeEnum;
import com.dy.yunying.api.enums.ZnfxCodeEnum;
import com.dy.yunying.api.req.znfx.AdPlanAnalyseReq;
import com.dy.yunying.api.req.znfx.AdPlanOverviewDto;
import com.dy.yunying.api.resp.znfx.AdPlanAnalyseRes;
import com.dy.yunying.api.resp.znfx.AdPlanDataExportRes;
import com.dy.yunying.api.resp.znfx.AdPlanReportRes;
import com.dy.yunying.api.utils.AdPlanAttrUtils;
import com.dy.yunying.biz.dao.znfx.AdPlanAnalyseDao;
import com.dy.yunying.biz.dao.znfx.AdPlanAnalyseReportDao;
import com.dy.yunying.biz.service.znfx.AdPlanAnalyseService;
import com.google.api.client.util.Lists;
import com.pig4cloud.pig.common.core.constant.enums.PlatformTypeEnum;
import com.pig4cloud.pig.common.core.util.R;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 计划属性分析
 * @author chenxiang
 * @className AdPlanAnalyseServiceImpl
 * @date 2023-3-22 11:03
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AdPlanAnalyseServiceImpl implements AdPlanAnalyseService {

	private final AdPlanAnalyseDao adPlanAnalyseDao;

	private final AdPlanAnalyseReportDao adPlanAnalyseReportDao;

	/**
	 * 计划属性分析图表
	 * @param record
	 * @return
	 */
	@Override
	public R chartData(AdPlanAnalyseReq record){
		try{
			// 查询计划属性
			List<AdPlanAnalyseRes> list = adPlanAnalyseDao.adPlanData(record);
			String platformId = record.getPlatformId();
			// 统计图标数据
			List<ChartVO> chartList = Lists.newArrayList();
			if (PlatformTypeEnum.TT.getValue().equals(platformId)){
				ttChartData(list, chartList);
			}else if (PlatformTypeEnum.GDT.getValue().equals(platformId)){
				gdtChartData(list, chartList);
			}else if (PlatformTypeEnum.KS.getValue().equals(platformId)){
				ksChartData(list, chartList);
			}else if (PlatformTypeEnum.BD.getValue().equals(platformId)){
				bdChartData(list, chartList);
			}else{
				defaultChartData(list, chartList);
			}
			return R.ok(chartList);
		} catch (Exception e){
			log.error("计划属性分析图表操作异常：{}", e);
			return R.failed("操作异常，请稍后再试");
		}
	}

	/**
	 * 计划分析计划汇总
	 * @param record
	 * @return
	 */
	@Override
	public R adPlanCollect(AdPlanAnalyseReq record){
		List<AdPlanReportRes> list = adPlanAnalyseDao.adPlanCollect(record);
		return R.ok(CollectionUtils.isNotEmpty(list) ? list.get(0) : null);
	}

	/**
	 * 导出列表
	 * @param req
	 * @return
	 */
	@Override
	public List<AdPlanDataExportRes> exportDataList(AdPlanOverviewDto req){
		if (1 == req.getType()){
			req.setQueryColumn("adid");
		}else{
			req.setCycleType(1);
		}
		return adPlanAnalyseReportDao.list(req);
	}

	private void ttChartData(List<AdPlanAnalyseRes> list, List<ChartVO> chartList){
		// 头条 - 投放范围
		Map<String, Long> deliveryRangeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getDeliveryRange()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.TT_DELIVERY_RANGE.getOrDefault(s.getDeliveryRange(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(deliveryRangeMap, chartList, ZnfxCodeEnum.RANGE.getName(), ZnfxCodeEnum.RANGE.getCode());
		// 头条 - 预算类型
		Map<String, Long> budgetModeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getBudgetMode()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.TT_BUDGET_MODE.getOrDefault(s.getBudgetMode(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(budgetModeMap, chartList, ZnfxCodeEnum.BUDGET.getName(), ZnfxCodeEnum.BUDGET.getCode());
		// 头条 - 下载方式
		Map<String, Long> downloadTypeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getDownloadType()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.TT_DOWNLOAD_TYPE.getOrDefault(s.getDownloadType(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(downloadTypeMap, chartList, ZnfxCodeEnum.APPDOWNLOAD.getName(), ZnfxCodeEnum.APPDOWNLOAD.getCode());
		// 头条 - 转化目标
		Map<String, Long> externalActionMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getExternalAction()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.TT_EXTERNAL_ACTION.getOrDefault(s.getExternalAction(), AdPlanAttrUtils.OTHER)
								+ (StringUtils.isNotBlank(s.getDeepExternalAction()) ? "-" + AdPlanAttrUtils.TT_DEEP_EXTERNAL_ACTION.getOrDefault(s.getDeepExternalAction(), AdPlanAttrUtils.OTHER) : ""),
						Collectors.counting()));
		dealChart(externalActionMap, chartList, ZnfxCodeEnum.EXTERNAL.getName(), ZnfxCodeEnum.EXTERNAL.getCode());
		// 头条 - 性别
		Map<String, Long> genderMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getGender()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.TT_GENDER.getOrDefault(s.getGender(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(genderMap, chartList, ZnfxCodeEnum.ADSEX.getName(), ZnfxCodeEnum.ADSEX.getCode());
		// 头条 - 年龄
		Map<String, Long> ageMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getAge()))
				.flatMap(s -> Arrays.stream(dealValue(s.getAge()).split(",")))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.TT_AGE.getOrDefault(s, AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(ageMap, chartList, ZnfxCodeEnum.ADAGE.getName(), ZnfxCodeEnum.ADAGE.getCode());
		// 头条 - 行为兴趣
		Map<String, Long> interestActionModeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getInterestActionMode()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.TT_INTEREST_ACTION_MODE.getOrDefault(s.getInterestActionMode(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(interestActionModeMap, chartList, ZnfxCodeEnum.INTEREST.getName(), ZnfxCodeEnum.INTEREST.getCode());
		// 头条 - 设备类型
		Map<String, Long> deviceTypeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getDeviceType()))
				.flatMap(s -> Arrays.stream(dealValue(s.getDeviceType()).split(",")))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.TT_DEVICE_TYPE.getOrDefault(s, AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(deviceTypeMap, chartList, ZnfxCodeEnum.DEVICE.getName(), ZnfxCodeEnum.DEVICE.getCode());
		// 头条 - 受众网络类型
		Map<String, Long> acMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getAc()))
				.flatMap(s -> Arrays.stream(dealValue(s.getAc()).split(",")))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.TT_AC.getOrDefault(s, AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(acMap, chartList, ZnfxCodeEnum.NETWORK.getName(), ZnfxCodeEnum.NETWORK.getCode());
		// 头条 - 运营商
		Map<String, Long> carrierMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getCarrier()))
				.flatMap(s -> Arrays.stream(dealValue(s.getCarrier()).split(",")))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.TT_CARRIER.getOrDefault(s, AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(carrierMap, chartList, ZnfxCodeEnum.OPERATOR.getName(), ZnfxCodeEnum.OPERATOR.getCode());
		// 头条 - 过滤已转化用户
		Map<String, Long> hideIfConvertedMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getHideIfConverted()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.TT_HIDE_IF_CONVERTED.getOrDefault(s.getHideIfConverted(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(hideIfConvertedMap, chartList, ZnfxCodeEnum.FILTEREXTERNAL.getName(), ZnfxCodeEnum.FILTEREXTERNAL.getCode());
		// 头条 - 出价方式
		Map<String, Long> smartBidTypeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getSmartBidType()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.TT_SMART_BID_TYPE.getOrDefault(s.getSmartBidType(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(smartBidTypeMap, chartList, ZnfxCodeEnum.BID.getName(), ZnfxCodeEnum.BID.getCode());
		// 头条 - 调整自动出价
		Map<String, Long> adjustCpaMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getAdjustCpa()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.TT_ADJUST_CPA.getOrDefault(s.getAdjustCpa(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(adjustCpaMap, chartList, ZnfxCodeEnum.AUTOBID.getName(), ZnfxCodeEnum.AUTOBID.getCode());
		// 头条 - 投放时间
		Map<String, Long> scheduleTypeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getScheduleType()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.TT_SCHEDULE_TYPE.getOrDefault(s.getScheduleType(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(scheduleTypeMap, chartList, ZnfxCodeEnum.ADTIME.getName(), ZnfxCodeEnum.ADTIME.getCode());
		// 头条 - 深度优化方式
		Map<String, Long> deepBidTypeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getDeepBidType()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.TT_DEEP_BID_TYPE.getOrDefault(s.getDeepBidType(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(deepBidTypeMap, chartList, ZnfxCodeEnum.DEEPBID.getName(), ZnfxCodeEnum.DEEPBID.getCode());
	}

	private void gdtChartData(List<AdPlanAnalyseRes> list, List<ChartVO> chartList){
		// 广点通 - 投放范围
		Map<String, Long> deliveryRangeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getDeliveryRange()))
				.flatMap(s -> Arrays.stream(dealValue(s.getDeliveryRange()).split(",")))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.GDT_DELIVERY_RANGE.getOrDefault(s, AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(deliveryRangeMap, chartList, ZnfxCodeEnum.RANGE.getName(), ZnfxCodeEnum.RANGE.getCode());
		// 广点通 - 预算类型
		Map<String, Long> budgetModeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getBudgetMode()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.GDT_BUDGET_MODE.getOrDefault(s.getBudgetMode(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(budgetModeMap, chartList, ZnfxCodeEnum.BUDGET.getName(), ZnfxCodeEnum.BUDGET.getCode());
		// 广点通 - 下载方式
		Map<String, Long> downloadTypeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getDownloadType()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.GDT_DOWNLOAD_TYPE.getOrDefault(s.getDownloadType(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(downloadTypeMap, chartList, ZnfxCodeEnum.APPDOWNLOAD.getName(), ZnfxCodeEnum.APPDOWNLOAD.getCode());
		// 广点通 - 转化目标
		Map<String, Long> externalActionMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getExternalAction()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.GDT_EXTERNAL_ACTION.getOrDefault(s.getExternalAction(), AdPlanAttrUtils.OTHER)
								+ (StringUtils.isNotBlank(s.getDeepExternalAction()) ? "-" + AdPlanAttrUtils.GDT_DEEP_EXTERNAL_ACTION.getOrDefault(s.getDeepExternalAction(), AdPlanAttrUtils.OTHER) : ""),
						Collectors.counting()));
		dealChart(externalActionMap, chartList, ZnfxCodeEnum.EXTERNAL.getName(), ZnfxCodeEnum.EXTERNAL.getCode());
		// 广点通 - 性别
		Map<String, Long> genderMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getGender()))
				.flatMap(s -> Arrays.stream(dealValue(s.getGender()).split(",")))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.GDT_GENDER.getOrDefault(s, AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(genderMap, chartList, ZnfxCodeEnum.ADSEX.getName(), ZnfxCodeEnum.ADSEX.getCode());
		// 广点通 - 年龄
		List<String> ageList = this.gdtAge(list);
		if (CollectionUtils.isNotEmpty(ageList)){
			Map<String, Long> ageMap = ageList.stream()
					.collect(Collectors.groupingBy(s -> s, Collectors.counting()));
			dealChart(ageMap, chartList, ZnfxCodeEnum.ADAGE.getName(), ZnfxCodeEnum.ADAGE.getCode());
		}
		/*// 广点通 - 行为兴趣
		Map<String, Long> interestActionModeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getInterestActionMode()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.GDT_INTEREST_ACTION_MODE.getOrDefault(s.getInterestActionMode(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(interestActionModeMap, chartList, ZnfxCodeEnum.INTEREST.getName(), ZnfxCodeEnum.INTEREST.getCode());
		// 广点通 - 设备类型
		Map<String, Long> deviceTypeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getDeviceType()))
				.flatMap(s -> Arrays.stream(dealValue(s.getDeviceType()).split(",")))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.GDT_DEVICE_TYPE.getOrDefault(s, AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(deviceTypeMap, chartList, ZnfxCodeEnum.DEVICE.getName(), ZnfxCodeEnum.DEVICE.getCode());*/
		// 广点通 - 受众网络类型
		Map<String, Long> acMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getAc()))
				.flatMap(s -> Arrays.stream(dealValue(s.getAc()).split(",")))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.GDT_AC.getOrDefault(s, AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(acMap, chartList, ZnfxCodeEnum.NETWORK.getName(), ZnfxCodeEnum.NETWORK.getCode());
		// 广点通 - 运营商
		Map<String, Long> carrierMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getCarrier()))
				.flatMap(s -> Arrays.stream(dealValue(s.getCarrier()).split(",")))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.GDT_CARRIER.getOrDefault(s, AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(carrierMap, chartList, ZnfxCodeEnum.OPERATOR.getName(), ZnfxCodeEnum.OPERATOR.getCode());
		// 广点通 - 过滤已转化用户
		Map<String, Long> hideIfConvertedMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getHideIfConverted()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.GDT_HIDE_IF_CONVERTED.getOrDefault(s.getHideIfConverted(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(hideIfConvertedMap, chartList, ZnfxCodeEnum.FILTEREXTERNAL.getName(), ZnfxCodeEnum.FILTEREXTERNAL.getCode());
		// 广点通 - 出价方式
		Map<String, Long> smartBidTypeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getSmartBidType()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.GDT_SMART_BID_TYPE.getOrDefault(s.getSmartBidType(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(smartBidTypeMap, chartList, ZnfxCodeEnum.BID.getName(), ZnfxCodeEnum.BID.getCode());
	/*	// 广点通 - 调整自动出价
		Map<String, Long> adjustCpaMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getAdjustCpa()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.GDT_ADJUST_CPA.getOrDefault(s.getAdjustCpa(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(adjustCpaMap, chartList, ZnfxCodeEnum.AUTOBID.getName(), ZnfxCodeEnum.AUTOBID.getCode());*/
		// 广点通 - 投放时间
		Map<String, Long> scheduleTypeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getScheduleType()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.GDT_SCHEDULE_TYPE.getOrDefault(s.getScheduleType(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(scheduleTypeMap, chartList, ZnfxCodeEnum.ADTIME.getName(), ZnfxCodeEnum.ADTIME.getCode());
		// 广点通 - 深度优化方式
		Map<String, Long> deepBidTypeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getDeepBidType()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.GDT_DEEP_BID_TYPE.getOrDefault(s.getDeepBidType(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(deepBidTypeMap, chartList, ZnfxCodeEnum.DEEPBID.getName(), ZnfxCodeEnum.DEEPBID.getCode());
	}

	private void ksChartData(List<AdPlanAnalyseRes> list, List<ChartVO> chartList){
		// 快手 - 投放范围
		Map<String, Long> deliveryRangeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getDeliveryRange()))
				.flatMap(s -> Arrays.stream(dealValue(s.getDeliveryRange()).split(",")))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.KS_DELIVERY_RANGE.getOrDefault(s, AdPlanAttrUtils.UNKNOWN), Collectors.counting()));
		dealChart(deliveryRangeMap, chartList, ZnfxCodeEnum.RANGE.getName(), ZnfxCodeEnum.RANGE.getCode());
		// 快手 - 预算类型
		Map<String, Long> budgetModeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getBudgetMode()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.KS_BUDGET_MODE.getOrDefault(s.getBudgetMode(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(budgetModeMap, chartList, ZnfxCodeEnum.BUDGET.getName(), ZnfxCodeEnum.BUDGET.getCode());
		// 快手 - 下载方式
		Map<String, Long> downloadTypeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getDownloadType()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.KS_DOWNLOAD_TYPE.getOrDefault(s.getDownloadType(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(downloadTypeMap, chartList, ZnfxCodeEnum.APPDOWNLOAD.getName(), ZnfxCodeEnum.APPDOWNLOAD.getCode());
		// 快手 - 转化目标
		Map<String, Long> externalActionMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getExternalAction()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.KS_EXTERNAL_ACTION.getOrDefault(s.getExternalAction(), AdPlanAttrUtils.OTHER)
								+ (StringUtils.isNotBlank(s.getDeepExternalAction()) ? "-" + AdPlanAttrUtils.KS_DEEP_EXTERNAL_ACTION.getOrDefault(s.getDeepExternalAction(), AdPlanAttrUtils.OTHER) : ""),
						Collectors.counting()));
		dealChart(externalActionMap, chartList, ZnfxCodeEnum.EXTERNAL.getName(), ZnfxCodeEnum.EXTERNAL.getCode());
		// 快手 - 性别
		Map<String, Long> genderMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getGender()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.KS_GENDER.getOrDefault(s.getGender(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(genderMap, chartList, ZnfxCodeEnum.ADSEX.getName(), ZnfxCodeEnum.ADSEX.getCode());
		// 快手 - 年龄
		Map<String, Long> ageMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getAge()))
				.flatMap(s -> Arrays.stream(dealValue(s.getAge()).split(",")))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.KS_AGE.getOrDefault(s, AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(ageMap, chartList, ZnfxCodeEnum.ADAGE.getName(), ZnfxCodeEnum.ADAGE.getCode());
		/*// 快手 - 行为兴趣
		Map<String, Long> interestActionModeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getInterestActionMode()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.KS_INTEREST_ACTION_MODE.getOrDefault(s.getInterestActionMode(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(interestActionModeMap, chartList, ZnfxCodeEnum.INTEREST.getName(), ZnfxCodeEnum.INTEREST.getCode());*/
		// 快手 - 设备类型
		Map<String, Long> deviceTypeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getDeviceType()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.KS_DEVICE_TYPE.getOrDefault(s.getDeviceType(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(deviceTypeMap, chartList, ZnfxCodeEnum.DEVICE.getName(), ZnfxCodeEnum.DEVICE.getCode());
		// 快手 - 受众网络类型
		Map<String, Long> acMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getAc()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.KS_AC.getOrDefault(s.getAc(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(acMap, chartList, ZnfxCodeEnum.NETWORK.getName(), ZnfxCodeEnum.NETWORK.getCode());
		/*// 快手 - 运营商
		Map<String, Long> carrierMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getCarrier()))
				.flatMap(s -> Arrays.stream(dealValue(s.getCarrier()).split(",")))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.KS_CARRIER.getOrDefault(s, AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(carrierMap, chartList, ZnfxCodeEnum.OPERATOR.getName(), ZnfxCodeEnum.OPERATOR.getCode());*/
		// 快手 - 过滤已转化用户
		Map<String, Long> hideIfConvertedMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getHideIfConverted()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.KS_HIDE_IF_CONVERTED.getOrDefault(s.getHideIfConverted(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(hideIfConvertedMap, chartList, ZnfxCodeEnum.FILTEREXTERNAL.getName(), ZnfxCodeEnum.FILTEREXTERNAL.getCode());
		// 快手 - 出价方式
		Map<String, Long> smartBidTypeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getSmartBidType()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.KS_SMART_BID_TYPE.getOrDefault(s.getSmartBidType(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(smartBidTypeMap, chartList, ZnfxCodeEnum.BID.getName(), ZnfxCodeEnum.BID.getCode());
		// 快手 - 调整自动出价
		Map<String, Long> adjustCpaMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getAdjustCpa()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.KS_ADJUST_CPA.getOrDefault(s.getAdjustCpa(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(adjustCpaMap, chartList, ZnfxCodeEnum.AUTOBID.getName(), ZnfxCodeEnum.AUTOBID.getCode());
		// 快手 - 投放时间
		Map<String, Long> scheduleTypeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getScheduleType()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.KS_SCHEDULE_TYPE.getOrDefault(s.getScheduleType(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(scheduleTypeMap, chartList, ZnfxCodeEnum.ADTIME.getName(), ZnfxCodeEnum.ADTIME.getCode());
		/*// 快手 - 深度优化方式
		Map<String, Long> deepBidTypeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getDeepBidType()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.KS_DEEP_BID_TYPE.getOrDefault(s.getDeepBidType(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(deepBidTypeMap, chartList, ZnfxCodeEnum.DEEPBID.getName(), ZnfxCodeEnum.DEEPBID.getCode());*/
	}
	// 百度数据
	private void bdChartData(List<AdPlanAnalyseRes> list, List<ChartVO> chartList){
		// 百度 - 投放范围
		Map<String, Long> deliveryRangeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getDeliveryRange()))
				.flatMap(s -> Arrays.stream(dealValue(s.getDeliveryRange()).split(",")))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.BD_DELIVERY_RANGE.getOrDefault(s, AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(deliveryRangeMap, chartList, ZnfxCodeEnum.RANGE.getName(), ZnfxCodeEnum.RANGE.getCode());
		// 百度 - 预算类型
		Map<String, Long> budgetModeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getBudgetMode()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.BD_BUDGET_MODE.getOrDefault(s.getBudgetMode(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(budgetModeMap, chartList, ZnfxCodeEnum.BUDGET.getName(), ZnfxCodeEnum.BUDGET.getCode());
		// 百度 - 下载方式
		Map<String, Long> downloadTypeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getDownloadType()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.BD_DOWNLOAD_TYPE.getOrDefault(s.getDownloadType(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(downloadTypeMap, chartList, ZnfxCodeEnum.APPDOWNLOAD.getName(), ZnfxCodeEnum.APPDOWNLOAD.getCode());
		// 百度 - 转化目标
		Map<String, Long> externalActionMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getExternalAction()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.BD_EXTERNAL_ACTION.getOrDefault(s.getExternalAction(), AdPlanAttrUtils.OTHER)
								+ (StringUtils.isNotBlank(s.getDeepExternalAction()) ? "-" + AdPlanAttrUtils.BD_DEEP_EXTERNAL_ACTION.getOrDefault(s.getDeepExternalAction(), AdPlanAttrUtils.OTHER) : ""),
						Collectors.counting()));
		dealChart(externalActionMap, chartList, ZnfxCodeEnum.EXTERNAL.getName(), ZnfxCodeEnum.EXTERNAL.getCode());
		// 百度 - 性别
		Map<String, Long> genderMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getGender()))
				.flatMap(s -> Arrays.stream(dealValue(s.getGender()).split(",")))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.BD_GENDER.getOrDefault(s, AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(genderMap, chartList, ZnfxCodeEnum.ADSEX.getName(), ZnfxCodeEnum.ADSEX.getCode());
		// 百度 - 年龄
		Map<String, Long> ageMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getAge()))
				.flatMap(s -> Arrays.stream(dealValue(s.getAge()).split(",")))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.BD_AGE.getOrDefault(s, AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(ageMap, chartList, ZnfxCodeEnum.ADAGE.getName(), ZnfxCodeEnum.ADAGE.getCode());
		// 百度 - 行为兴趣
		Map<String, Long> interestActionModeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getInterestActionMode()))
				.flatMap(s -> Arrays.stream(dealValue(s.getInterestActionMode()).split(",")))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.BD_INTEREST_ACTION_MODE.getOrDefault(s, AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(interestActionModeMap, chartList, ZnfxCodeEnum.INTEREST.getName(), ZnfxCodeEnum.INTEREST.getCode());
		// 百度 - 设备类型
		Map<String, Long> deviceTypeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getDeviceType()))
				.flatMap(s -> Arrays.stream(dealValue(s.getDeviceType()).split(",")))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.BD_DEVICE_TYPE.getOrDefault(s, AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(deviceTypeMap, chartList, ZnfxCodeEnum.DEVICE.getName(), ZnfxCodeEnum.DEVICE.getCode());
		// 百度 - 受众网络类型
		Map<String, Long> acMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getAc()))
				.flatMap(s -> Arrays.stream(dealValue(s.getAc()).split(",")))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.BD_AC.getOrDefault(s, AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(acMap, chartList, ZnfxCodeEnum.NETWORK.getName(), ZnfxCodeEnum.NETWORK.getCode());
		// 百度 - 运营商
		Map<String, Long> carrierMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getCarrier()))
				.flatMap(s -> Arrays.stream(dealValue(s.getCarrier()).split(",")))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.BD_CARRIER.getOrDefault(s, AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(carrierMap, chartList, ZnfxCodeEnum.OPERATOR.getName(), ZnfxCodeEnum.OPERATOR.getCode());
		// 百度 - 过滤已转化用户
		Map<String, Long> hideIfConvertedMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getHideIfConverted()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.BD_HIDE_IF_CONVERTED.getOrDefault(s.getHideIfConverted(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(hideIfConvertedMap, chartList, ZnfxCodeEnum.FILTEREXTERNAL.getName(), ZnfxCodeEnum.FILTEREXTERNAL.getCode());
		// 百度 - 出价方式
		Map<String, Long> smartBidTypeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getSmartBidType()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.BD_SMART_BID_TYPE.getOrDefault(s.getSmartBidType(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(smartBidTypeMap, chartList, ZnfxCodeEnum.BID.getName(), ZnfxCodeEnum.BID.getCode());
/*		// 百度 - 调整自动出价
		Map<String, Long> adjustCpaMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getAdjustCpa()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.BD_ADJUST_CPA.getOrDefault(s.getAdjustCpa(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(adjustCpaMap, chartList, ZnfxCodeEnum.AUTOBID.getName(), ZnfxCodeEnum.AUTOBID.getCode());*/
		// 百度 - 投放时间
		Map<String, Long> scheduleTypeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getScheduleType()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.BD_SCHEDULE_TYPE.getOrDefault(s.getScheduleType(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(scheduleTypeMap, chartList, ZnfxCodeEnum.ADTIME.getName(), ZnfxCodeEnum.ADTIME.getCode());
/*		// 百度 - 深度优化方式
		Map<String, Long> deepBidTypeMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getDeepBidType()))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.BD_DEEP_BID_TYPE.getOrDefault(s.getDeepBidType(), AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(deepBidTypeMap, chartList, ZnfxCodeEnum.DEEPBID.getName(), ZnfxCodeEnum.DEEPBID.getCode());*/
		// 百度 - 学历
		Map<String, Long> educationMap = list.stream()
				.filter(s -> StringUtils.isNotBlank(s.getEducation()))
				.flatMap(s -> Arrays.stream(dealValue(s.getEducation()).split(",")))
				.collect(Collectors.groupingBy(s -> AdPlanAttrUtils.BD_EDUCATION.getOrDefault(s, AdPlanAttrUtils.OTHER), Collectors.counting()));
		dealChart(educationMap, chartList, ZnfxCodeEnum.EDUCATION.getName(), ZnfxCodeEnum.EDUCATION.getCode());
	}

	private void defaultChartData(List<AdPlanAnalyseRes> list, List<ChartVO> chartList){
		// 头条 - 投放范围
		Map<String, Long> dataMap = new HashMap<>();
		dealChart(dataMap, chartList, ZnfxCodeEnum.RANGE.getName(), ZnfxCodeEnum.RANGE.getCode());
		// 头条 - 预算类型
		dealChart(dataMap, chartList, ZnfxCodeEnum.BUDGET.getName(), ZnfxCodeEnum.BUDGET.getCode());
		// 头条 - 下载方式
		dealChart(dataMap, chartList, ZnfxCodeEnum.APPDOWNLOAD.getName(), ZnfxCodeEnum.APPDOWNLOAD.getCode());
		// 头条 - 转化目标
		dealChart(dataMap, chartList, ZnfxCodeEnum.EXTERNAL.getName(), ZnfxCodeEnum.EXTERNAL.getCode());
		// 头条 - 性别
		dealChart(dataMap, chartList, ZnfxCodeEnum.ADSEX.getName(), ZnfxCodeEnum.ADSEX.getCode());
		// 头条 - 年龄
		dealChart(dataMap, chartList, ZnfxCodeEnum.ADAGE.getName(), ZnfxCodeEnum.ADAGE.getCode());
		// 头条 - 行为兴趣
		dealChart(dataMap, chartList, ZnfxCodeEnum.INTEREST.getName(), ZnfxCodeEnum.INTEREST.getCode());
		// 头条 - 设备类型
		dealChart(dataMap, chartList, ZnfxCodeEnum.DEVICE.getName(), ZnfxCodeEnum.DEVICE.getCode());
		// 头条 - 受众网络类型
		dealChart(dataMap, chartList, ZnfxCodeEnum.NETWORK.getName(), ZnfxCodeEnum.NETWORK.getCode());
		// 头条 - 运营商
		dealChart(dataMap, chartList, ZnfxCodeEnum.OPERATOR.getName(), ZnfxCodeEnum.OPERATOR.getCode());
		// 头条 - 过滤已转化用户
		dealChart(dataMap, chartList, ZnfxCodeEnum.FILTEREXTERNAL.getName(), ZnfxCodeEnum.FILTEREXTERNAL.getCode());
		// 头条 - 出价方式
		dealChart(dataMap, chartList, ZnfxCodeEnum.BID.getName(), ZnfxCodeEnum.BID.getCode());
		// 头条 - 调整自动出价
		dealChart(dataMap, chartList, ZnfxCodeEnum.AUTOBID.getName(), ZnfxCodeEnum.AUTOBID.getCode());
		// 头条 - 投放时间
		dealChart(dataMap, chartList, ZnfxCodeEnum.ADTIME.getName(), ZnfxCodeEnum.ADTIME.getCode());
		// 头条 - 深度优化方式
		dealChart(dataMap, chartList, ZnfxCodeEnum.DEEPBID.getName(), ZnfxCodeEnum.DEEPBID.getCode());
	}

	// 广点通 - 年龄 - 计算
	private List<String> gdtAge(List<AdPlanAnalyseRes> list){
		List<String> ageList = Lists.newArrayList();
		list.forEach(s -> {
			String age = s.getAge();
			if (StringUtils.isBlank(age) || "UNLIMITED".equals(age)){
				ageList.add("不限");
			}else{
				List<Map> list1 = JSON.parseArray(s.getAge(), Map.class);
				list1.forEach(v ->{
					ageList.add(v.get("min") + "-" + v.get("max") + "岁");
				});
			}
		});
		return ageList;
	}

	private static void dealChart(Map<String, Long> dataMap, List<ChartVO> chartList, String title, String target){
		List<ChartDataDetail> detailList = Lists.newArrayList();
		for (Map.Entry<String, Long> entry : dataMap.entrySet()) {
			ChartDataDetail data = new ChartDataDetail();
			data.setName(entry.getKey());
			data.setValue(entry.getValue());
			detailList.add(data);
		}
		ChartData chartData = new ChartData();
		chartData.setType(ChartTypeEnum.PIE.getCode());
		chartData.setData(detailList);

		List<ChartData> dataList = new ArrayList<>();
		dataList.add(chartData);

		ChartVO chartVO = new ChartVO();
		chartVO.setTitle(title);
		chartVO.setTarget(target);
		chartVO.setSeries(dataList);
		chartList.add(chartVO);
	}
	private static String dealValue(String value){
		return value.replace("[", "")
				.replace("]", "")
				.replaceAll("\"", "")
				.replaceAll("'","");
	}
}
